<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1.设计（一）-如何让可视化设计更加清晰-分清信息主次，建立视觉层次</title>
    <style>
        #app {
            border: 1px solid #ccc;
            width: 1200px;
            height: 600px;
        }
    </style>
</head>
<body>
    <div id="app"></div>

    <script src="https://d3js.org/d3.v6.js"></script>
    <script src="https://unpkg.com/spritejs/dist/spritejs.min.js"></script>
    <script src="https://unpkg.com/@qcharts/core/dist/index.js"></script>

    <script type="module">

        (async function() {

            // 1.首先看我们有什么数据 (data.json)
            // 获取csv格式的文本数据（逗号或者回车分隔的文本）
            const rawData = await (await fetch('beijing_2014.csv')).text();
            
            // 2.我们想了解什么：
            // 这里使用d3的方法对原始数据进行分类处理
            
            const data = d3.csvParse(rawData).filter(d => new Date(d.Date).getMonth() < 3);

            // 不相关
            // const dataset = data
            // .map(d => {
            //     return {
            //         temperature: Number(d['Temperature(Celsius)(avg)']),
            //         humdity: Number(d['Humidity(%)(avg)']),
            //         category: '平均气温与湿度'
            //     }
            // });

            
            // 正相关
            const dataset = data
            .map(d => {
                return {
                    temperature: Number(d['Temperature(Celsius)(avg)']),
                    tdp: Number(d['Dew Point(Celsius)(avg)']),
                    category: '平均气温与露点'}
                });
            
            //露点排序
            let dataset2 = [...dataset].sort((a,b) => a.tdp-b.tdp);
            // 对相同露点的温度进行分组
            dataset2 = dataset2.reduce((a,b)=>{
                let curr = a[a.length-1];
                if (curr && curr.tdp === b.tdp) { 
                    curr.temperature.push(b.temperature) 
                }else { 
                    a.push({ 
                        temperature: [b.temperature], 
                        tdp: b.tdp 
                    }) 
                }
                return a
            }, []);

            // 最后将露点平均温度计算出来
            dataset2 = dataset2.map(d => { 
                d.category = '露点平均气温' ;
                d.temperature = Math.round(d.temperature.reduce((a, b) => a + b) / d.temperature.length); 
                return d;
            })
            // 3.用哪种可视化方式呈现数据：折线图，使用qcharts图标库进行图表展示
            // 转换数据为坐标点信息
            const { Chart, Scatter, Line, Legend, Tooltip, Axis } = qcharts;
            // 3.1创建图表
            const chart = new Chart({
                container:"#app"
            });
            let clientRect = { bottom: 50 };
            // 传入数据
            chart.source([ ...dataset, ...dataset2 ], {
                row:"category",
                value:"temperature",
                text:"tdp"
            });

            // 分别用散点和曲线图来呈现数据了
            const ds = chart.dataset;
            const d1 = ds.selectRows("平均气温与露点");
            const d2 = ds.selectRows('露点平均气温');

            // 3.2 散点图
            const scatter = new Scatter({ clientRect, showGuideLine: true, }).source(d1);

            // 曲线图
            const line = new Line().source(d2);
            line.style('line', function(attrs, data, i) { 
                return { smooth: true, lineWidth: 3, strokeColor: '#0a0' };
            });
            line.style('point', function(attrs) { 
                return { display: 'none' };
            });

            // 3.3创建横、纵两个坐标轴（Axis）、提示（ToolTip）和一个图例（Legend)
            const axisBottom = new Axis();

            const toolTip = new Tooltip({ 
                title: (data) => '露点与温度：', 
                formatter: (data) => { return `露点：${data.tdp} 温度：${data.temperature} ` }
            });
            const legend = new Legend();
            const axisLeft = new Axis({ orient: 'left',clientRect }).style('axis', false).style('scale', false);

            chart.append([scatter, line, axisBottom, axisLeft, toolTip, legend]);
        }());
    </script>
</body>
</html>